package sdk.webview.fmc.com.fmcsdk.util;

import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;

import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.bouncycastle.util.encoders.Hex;

import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Base64;


//public class SM2Utils {
//    public static void sm2Encrypt() {
//        String dataString = "123456789";
//        String pubKey = "043dcf95a67d53f60f36608e76b4a482900115fccee642ecbbba6c31b78e750c04b5876b7a8603d65ba632fff3320ce4b9090ea8651157b8b40f2c576ac882d7e9";
//        String priKey = "8efab8ec34f822e0791c0f759f573d3697b1a4ba86a643d34d43824a70d30286";
//        XLog.i("明文：" + dataString);
//
//        // 获取随机的公私钥
//        byte[][] key = SM2Util.generateKeyPair();
//        byte[] publicKey = key[0];
//        byte[] privateKey = key[1];
//
////        XLog.i("私钥：" + privateKey.length + "  " + Util.byte2HexStr(privateKey));
////        XLog.i("公钥：" + Util.byte2HexStr(publicKey));
//
//        byte[] encryptByPublicKey = SM2Util.encrypt(Util.hexStr2Bytes(pubKey), dataString.getBytes());
//        XLog.i("公钥加密明文：" + Util.byte2HexStr(encryptByPublicKey));
//        XLog.i("私钥解密：" + new String(SM2Util.decrypt(Util.hexStr2Bytes(priKey), encryptByPublicKey)));
//
//        byte[] sign = SM2Util.sign(privateKey, encryptByPublicKey);
//        XLog.i("签名：" + Util.byte2HexStr(sign));
//        boolean verifySign = SM2Util.verifySign(publicKey, encryptByPublicKey, sign);
//        XLog.i("验签：" + verifySign);
//    }
//}

public class SM2Utils {
    public static String decrypt1(String cipherData, String privateKey) throws InvalidCipherTextException {
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
        //JS加密产生的密文
        byte[] cipherDataByte = Hex.decode(cipherData);

        //刚才的私钥Hex，先还原私钥
        BigInteger privateKeyD = new BigInteger(privateKey, 16);
        ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);
        //用私钥解密
        SM2Engine sm2Engine = new SM2Engine();
        sm2Engine.init(false, privateKeyParameters);
        //processBlock得到Base64格式，记得解码
        byte[] arrayOfBytes = new byte[0];
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            arrayOfBytes = Base64.getDecoder().decode(sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length));
        }
        //得到明文：
        String data = new String(arrayOfBytes);
        return data;
    }


    //数据加密
    public static String encode(String publicKey,String plaintext){
        byte[] bb = ByteUtils.fromHexString(publicKey);
        // 获取一条SM2曲线参数
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
        // 构造ECC算法参数，曲线方程、椭圆曲线G点、大整数N
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
        //提取公钥点
        ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(Hex.decode(publicKey));
        // 公钥前面的02或者03表示是压缩公钥，04表示未压缩公钥, 04的时候，可以去掉前面的04
        ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);

        SM2Engine sm2Engine = new SM2Engine();
        // 设置sm2为加密模式
        sm2Engine.init(true, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));

        byte[] arrayOfBytes = null;
        try {
            byte[] in = new byte[0];
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                in = Base64.getEncoder().encode(plaintext.getBytes());
            }
            arrayOfBytes = sm2Engine.processBlock(in, 0, in.length);
        } catch (Exception e) {
        }
        return Hex.toHexString(arrayOfBytes);
    }

    public static void main() throws Exception {
        String cipherData = "043409A606B96E9DB5E81F14B38F86DFC3714579E20C998B4933792FA1240E3BF8BEA2720E08067A1CEFE78BE83A645A464EC8EB1A6699C57CC53376B929E862EDA40E5C45B57ED9C47A0D153CE3F753B6F43FA23196C404047E7DEEE0BA9C7C20D9EA362C0CC7BD0EDF06DB6D30417AB6";
        String privateKey = "bd936dbb133e04fa59d6d31f65ff06261eda51dfd03bd2301e08bd99484dd21c";
       XLog.i(decrypt1(cipherData, privateKey));
        XLog.i(encode("043dcf95a67d53f60f36608e76b4a482900115fccee642ecbbba6c31b78e750c04b5876b7a8603d65ba632fff3320ce4b9090ea8651157b8b40f2c576ac882d7e9", "12345678"));
    }
}
